#pragma comment(linker, "/STACK:10000000")
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <set>
#include <map>
#include <cstdio>
#include <cassert>
#include <string>
#include <cstring>
#define ldb long double
#define LL long long
#define fi first
#define se second
#define fill(a, c) memset(a, c, sizeof(a))
#define sqr(a) ((a) * (a))
#define nextLine() {int c = 0; while((c = getchar()) != 10 && c != EOF);}
#define getBit(mask, k) (((mask) / pw[k]) % pw[1])
#define setBit(mask, k, l) (((mask) / pw[k + 1] * pw[1] + (l)) * pw[k] + ((mask) % pw[k]))
#define debug(a) cerr << #a << " = " << a << " ";
#define debugl(a) cerr << #a << " = " << a << "\n";
const ldb LDINF = 9128739847123.00;
const ldb eps = 1e-9;
const LL INF = 1ll << 58;
const ldb pi = fabsl(atan2(0.0, -1.0));
using namespace std;

const int MAXE = 20010;
const int MAXV = 3000;
int n, m;

int edges, next[MAXE], first[MAXV], end[MAXE];
LL cost[MAXE];
LL dst[1010][1010];
int t[1010];
int c[1010];

void addEdge(int i, int j, LL cst)
{
	next[edges] = first[i];
	first[i] = edges;
	end[edges] = j;
	cost[edges] = cst;
	edges++;
}
LL d[MAXV];
class compare
{
	public:
		bool operator() (int a, int b)
		{
			return d[a] < d[b] || d[a] == d[b] && a < b;
		}
};

set <int, compare> was;
bool usd[1010];
int x, y;
void Load()
{
	cin >> n >> m;
	cin >> x >> y;
	int i;
	memset(first, -1, sizeof first);
	int a, b; 
	LL c;
	for (i = 0; i < m; i++)
	{
		scanf("%d%d%I64d", &a, &b, &c);
		addEdge(a, b, c);
		addEdge(b, a, c);
	}
	for (int i = 1; i <= n; i++)
	{
		scanf("%d%d", &t[i], &::c[i]);
	}
}

void Solve()
{
	int ver;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			d[j] = INF;
		d[i] = 0;
		was.insert(i);
		while (!was.empty())
		{
			ver = *was.begin();
			was.erase(was.begin());
			for (int u = first[ver]; u != -1; u = next[u])
			{
				if (d[end[u]] > d[ver] + cost[u])
				{
					if (was.find(end[u]) != was.end())
						was.erase(end[u]);
					d[end[u]] = d[ver] + cost[u];
					was.insert(end[u]);
				}
			}
		}
		for (int j = 1; j <= n; j++)
		{
			dst[i][j] = d[j];
		}
	}
	for (int j = 1; j <= n; j++)
		d[j] = INF;
	d[x] = 0;
	ver = x;
	LL cmin = 0;
	while (cmin < INF)
	{
		usd[ver] = 1;
		if (ver == y)
		{
			cout << d[ver];
			return;
		}
		for (int j = 1; j <= n; j++)
		{
			if (dst[ver][j] > (LL)t[ver] || usd[j]) continue;
			if (d[j] > d[ver] + (LL)c[ver])
				d[j] = d[ver] + (LL)c[ver];
		}
		cmin = INF;
		for (int j = 1; j <= n; j++)
		{
			if (!usd[j] && cmin > d[j])
			{
				cmin = d[j];
				ver = j;
			}
		}
	}
	cout << "-1";
}

#define file "c"
int main()
{
	#ifndef ONLINE_JUDGE
		freopen(file".in", "rt", stdin);
		freopen(file".out", "wt", stdout);
	#endif
	Load();
	Solve();
	return 0;
}
